package com.hawkbrowser.webkit;
import java.util.concurrent.Callable;
import org.chromium.android_webview.AwBrowserContext;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwLayoutSizer;
import org.chromium.android_webview.AwSettings;
import org.chromium.base.ThreadUtils;
import org.chromium.content.browser.LoadUrlParams;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Picture;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeProvider;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.webkit.DownloadListener;
import android.widget.FrameLayout;
public class WebView extends FrameLayout {
private final static String PREFERENCES_NAME = "WebViewPrefs";
private AwContents mAwContents;
private AwBrowserContext mBrowserContext;
private ContentSettingsAdapter mWebSettings;
private WebViewContentsClientAdapter mContentsClientAdapter;
private AwContents.InternalAccessDelegate mInternalAccessDelegate;
/**
* Interface to listen for find results.
*/
public interface FindListener {
/**
* Notifies the listener about progress made by a find operation.
*
* @param activeMatchOrdinal the zero-based ordinal of the currently selected match
* @param numberOfMatches how many matches have been found
* @param isDoneCounting whether the find operation has actually completed. The listener
* may be notified multiple times while the
* operation is underway, and the numberOfMatches
* value should not be considered final unless
* isDoneCounting is true.
*/
public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,
boolean isDoneCounting);
}
/**
* Interface to listen for new pictures as they change.
*
* @deprecated This interface is now obsolete.
*/
@Deprecated
public interface PictureListener {
/**
* Used to provide notification that the WebView's picture has changed.
* See {@link WebView#capturePicture} for details of the picture.
*
* @param view the WebView that owns the picture
* @param picture the new picture. Applications targeting
* {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} or above
* will always receive a null Picture.
* @deprecated Deprecated due to internal changes.
*/
@Deprecated
public void onNewPicture(WebView view, Picture picture);
}
/**
* Transportation object for returning WebView across thread boundaries.
*/
public class WebViewTransport {
private WebView mWebview;
/**
* Sets the WebView to the transportation object.
*
* @param webview the WebView to transport
*/
public synchronized void setWebView(WebView webview) {
mWebview = webview;
}
/**
* Gets the WebView object.
*
* @return the transported WebView object
*/
public synchronized WebView getWebView() {
return mWebview;
}
}
public WebView(Context context) {
this(context, null);
}
public WebView(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.webViewStyle);
}
public WebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
SharedPreferences sharedPreferences = getContext().getSharedPreferences(
PREFERENCES_NAME, Context.MODE_PRIVATE);
if (mBrowserContext == null) {
mBrowserContext = new AwBrowserContext(sharedPreferences);
}
if(null == mInternalAccessDelegate) {
mInternalAccessDelegate = new InternalAccessAdapter();
}
mWebSettings = new ContentSettingsAdapter(new AwSettings(
getContext(), false, true));
mContentsClientAdapter = new WebViewContentsClientAdapter(this);
mAwContents = new AwContents(mBrowserContext, this,
mInternalAccessDelegate, mContentsClientAdapter,
new AwLayoutSizer(), mWebSettings.getAwSettings());
}
public void loadUrl(String url) {
mAwContents.loadUrl(new LoadUrlParams(url));
}
public boolean canGoBack() {
return mAwContents.canGoBack();
}
public void goBack() {
mAwContents.goBack();
}
public boolean canGoForward() {
return mAwContents.canGoForward();
}
public void goForward() {
mAwContents.goForward();
}
public String getUrl() {
return mAwContents.getUrl();
}
public void destroy() {
mAwContents.destroy();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mAwContents.onConfigurationChanged(newConfig);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
mAwContents.onAttachedToWindow();
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAwContents.onDetachedFromWindow();
}
@Override
public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
mAwContents.onFocusChanged(focused, direction, previouslyFocusedRect);
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
return mAwContents.onCreateInputConnection(outAttrs);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
return mAwContents.onKeyUp(keyCode, event);
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
return mAwContents.dispatchKeyEvent(event);
}
@SuppressLint("WrongCall")
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mAwContents.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void onSizeChanged(int w, int h, int ow, int oh) {
super.onSizeChanged(w, h, ow, oh);
mAwContents.onSizeChanged(w, h, ow, oh);
}
@Override
public void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
mAwContents.onContainerViewOverScrolled(scrollX, scrollY, clampedX, clampedY);
}
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mAwContents != null) {
mAwContents.onContainerViewScrollChanged(l, t, oldl, oldt);
}
}
@Override
public void computeScroll() {
mAwContents.computeScroll();
}
@Override
public void onVisibilityChanged(View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
mAwContents.onVisibilityChanged(changedView, visibility);
}
@Override
public void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
mAwContents.onWindowVisibilityChanged(visibility);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
return mAwContents.onTouchEvent(ev);
}
@SuppressLint("WrongCall")
@Override
public void onDraw(Canvas canvas) {
mAwContents.onDraw(canvas);
super.onDraw(canvas);
}
@SuppressLint("NewApi")
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider() {
AccessibilityNodeProvider provider =
mAwContents.getAccessibilityNodeProvider();
return provider == null ? super.getAccessibilityNodeProvider() : provider;
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(AwContents.class.getName());
mAwContents.onInitializeAccessibilityNodeInfo(info);
}
@Override
public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
super.onInitializeAccessibilityEvent(event);
event.setClassName(AwContents.class.getName());
mAwContents.onInitializeAccessibilityEvent(event);
}
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
return mAwContents.performAccessibilityAction(action, arguments);
}
public WebSettings getSettings() {
return mWebSettings;
}
public Bitmap getFavicon() {
return mAwContents.getFavicon();
}
private boolean checkNeedsPost() {
boolean needsPost = !ThreadUtils.runningOnUiThread();
if (!needsPost && mAwContents == null) {
throw new IllegalStateException(
"AwContents must be created if we are not posting!");
}
return needsPost;
}
public WebBackForwardList copyBackForwardList() {
return new WebBackForwardListChromium(
mAwContents.getNavigationHistory());
}
static void completeWindowCreation(WebView parent, WebView child) {
AwContents parentContents = parent.mAwContents;
AwContents childContents =
child == null ? null : child.mAwContents;
parentContents.supplyContentsForPopup(childContents);
}
public void setWebViewClient(WebViewClient client) {
mContentsClientAdapter.setWebViewClient(client);
}
public void setWebChromeClient(WebChromeClient client) {
mContentsClientAdapter.setWebChromeClient(client);
}
public String getTitle() {
return mAwContents.getTitle();
}
public int getProgress() {
if (mAwContents == null) return 100;
// No checkThread() because the value is cached java side (workaround for b/10533304).
return mAwContents.getMostRecentProgress();
}
public void reload() {
mAwContents.reload();
}
public void setDownloadListener(DownloadListener listener) {
mContentsClientAdapter.setDownloadListener(listener);
}
private class InternalAccessAdapter implements AwContents.InternalAccessDelegate {
@Override
public boolean drawChild(Canvas canvas, View child, long drawingTime) {
return WebView.super.drawChild(canvas, child, drawingTime);
}
@Override
public boolean super_onKeyUp(int keyCode, KeyEvent event) {
return WebView.super.onKeyUp(keyCode, event);
}
@Override
public boolean super_dispatchKeyEventPreIme(KeyEvent event) {
return WebView.super.dispatchKeyEventPreIme(event);
}
@Override
public boolean super_dispatchKeyEvent(KeyEvent event) {
return WebView.super.dispatchKeyEvent(event);
}
@Override
public boolean super_onGenericMotionEvent(MotionEvent event) {
return WebView.super.onGenericMotionEvent(event);
}
@Override
public void super_onConfigurationChanged(Configuration newConfig) {
WebView.super.onConfigurationChanged(newConfig);
}
@Override
public void super_scrollTo(int scrollX, int scrollY) {
// We're intentionally not calling super.scrollTo here to make testing easier.
WebView.this.scrollTo(scrollX, scrollY);
}
@Override
public void overScrollBy(int deltaX, int deltaY,
int scrollX, int scrollY,
int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY,
boolean isTouchEvent) {
// We're intentionally not calling super.scrollTo here to make testing easier.
WebView.this.overScrollBy(deltaX, deltaY, scrollX, scrollY,
scrollRangeX, scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
WebView.super.onScrollChanged(l, t, oldl, oldt);
}
@Override
public boolean awakenScrollBars() {
return WebView.super.awakenScrollBars();
}
@Override
public boolean super_awakenScrollBars(int startDelay, boolean invalidate) {
return WebView.super.awakenScrollBars(startDelay, invalidate);
}
@Override
public void setMeasuredDimension(int measuredWidth, int measuredHeight) {
WebView.super.setMeasuredDimension(measuredWidth, measuredHeight);
}
@Override
public int super_getScrollBarStyle() {
return WebView.super.getScrollBarStyle();
}
@Override
public boolean requestDrawGL(Canvas canvas) {
return false;
}
}
}